package server;

// This file contains material supporting section 10.9 of the textbook:
// "Object Oriented Software Engineering" and is issued under the open-source
// license found at www.lloseng.com

/*
 * SimpleServer.java   2001-02-08
 *
 * Copyright (c) 2000 Robert Laganiere and Timothy C. Lethbridge.
 * All Rights Reserved.
 *
 */




import db.parking.beans.Admin;
import db.parking.beans.Customer;
import db.parking.beans.Orders;
import db.tables.AdminCustomer;
import db.tables.AdminManager;
import db.tables.AdminOrders;
import java.util.Date;
import java.awt.List;
import java.awt.Color;
import java.sql.SQLException;
import java.sql.Timestamp;



import control.ConnectionManage;
import control.DBType;

import client.Message;

/**
 * The <code> SimpleServer </code> class is a simple subclass of the
 * <code> ocsf.server.AbstractServer </code> class. It allows testing of the
 * functionalities offered by the OCSF framework. The
 * <code> java.awt.List </code> instance is used to display informative
 * messages. This list is red when the server is closed, yellow when the server
 * is stopped and green when open.
 * 
 * @author Dr. Robert Lagani&egrave;re
 * @version February 2001
 * @see ocsf.server.AbstractServer
 */
public class SimpleServer extends AbstractServer {
	private List liste;
	
	//for time stamp= server current time
	long time;// = System.currentTimeMillis();
	Timestamp currTimestamp;// = new Timestamp(time);
	

	/**
	 * Creates a simple server. The default port is 12345.
	 * 
	 * @param liste
	 *            the liste on which information will be displayed.
	 */
	public SimpleServer(List liste) {
		super(12345);
		this.liste = liste;
	}

	/**
	 * Creates a simple server.
	 * 
	 * @param port
	 *            the port on which the server will listen.
	 * @param liste
	 *            the liste on which information will be displayed.
	 */
	public SimpleServer(int port, List liste) {
		super(port);
		this.liste = liste;
	}

	/**
	 * Hook method called each time a new client connection is accepted.
	 * 
	 * @param client
	 *            the connection connected to the client.
	 */
	synchronized protected void clientConnected(ConnectionToClient client) {
		liste.add("Client connected: " + client);
		liste.makeVisible(liste.getItemCount() - 1);
	}

	/**
	 * Hook method called each time a client disconnects.
	 * 
	 * @param client
	 *            the connection with the client.
	 */
	synchronized protected void clientDisconnected(ConnectionToClient client) {
		liste.add("Client disconnected: " + client);
		liste.makeVisible(liste.getItemCount() - 1);
	}

	/**
	 * Hook method called each time an exception is thrown in a
	 * ConnectionToClient thread.
	 * 
	 * @param client
	 *            the client that raised the exception.
	 * @param Throwable
	 *            the exception thrown.
	 */
	synchronized protected void clientException(ConnectionToClient client,
			Throwable exception) {
		liste.add("Client exception: " + exception + " with " + client);
		liste.makeVisible(liste.getItemCount() - 1);
	}

	/**
	 * Hook method called when the server stops accepting connections because an
	 * exception has been raised.
	 * 
	 * @param exception
	 *            the exception raised.
	 */
	protected void listeningException(Throwable exception) {
		liste.add("Listening exception: " + exception);
		liste.makeVisible(liste.getItemCount() - 1);
		liste.setBackground(Color.red);
	}

	/**
	 * Hook method called when the server stops accepting connections.
	 */
	protected void serverStopped() {
		liste.add("Server stopped");
		liste.makeVisible(liste.getItemCount() - 1);
		liste.setBackground(Color.yellow);
	}

	/**
	 * Hook method called when the server is clased.
	 */
	protected void serverClosed() {
		liste.add("Server closed");
		liste.makeVisible(liste.getItemCount() - 1);
		liste.setBackground(Color.red);
	}

	/**
	 * Hook method called when the server starts listening for connections.
	 */
	protected void serverStarted() {
		liste.add("Server started on port : " + this.getPort());
		liste.add("Waiting for users to connect...");
		liste.makeVisible(liste.getItemCount() - 1);
		liste.setBackground(Color.green);
	}

	/**
	 * Handles a command sent from one client to the server.
	 * 
	 * @param msg
	 *            the message sent.
	 * @param client
	 *            the connection connected to the client that sent the message.
	 */
	protected void handleMessageFromClient(Object msg, ConnectionToClient client) {

		System.out.println("server");
		ConnectionManage.getInstance().setDBType(DBType.MYSQL);

		Message tempMsg = (Message) msg;

		switch (tempMsg.getMsg()) {
		// orders handle
		case "AddOccasionalOrder":
			AddOccasionalOrder(msg);
			break;

		case "AddTemporaryOrder":
			AddTemporaryOrder(msg);
			break;
		
		case "AddSubscriberOrder":
			AddSubscriberOrder(msg);
			break;	
			
		case "CancellOrder": {
			//CancellOrder(msg);
			break;
			}
		
		case "SubmitComplaint": {
			complaintHandle(msg);
			break;
		}

		default:
			tempMsg.setStatus(false);
		}

		sendToAllClients(tempMsg);
	}

	private void AddOccasionalOrder(Object msg) {
		Message tempMsg = (Message) msg;
		try {
			Orders o = (Orders) tempMsg.getObj();
			
			//check if an Occasional customer with this ID exists
			Customer bean = AdminCustomer.getRow(o.getUid(),o.getType());
			if(bean == null)
			{
				liste.add("ERROR:User Has Entered An Invalid ID");
				tempMsg.setStatusMsg("Such Occasional User Does Not Exist");
				return;
			}
			long time = System.currentTimeMillis();//Set current time at this second to StartTime
			Timestamp currTimestamp = new Timestamp(time);
			o.setStartTime(currTimestamp);
			//check that entered leave time is not before the current time now
			if(currTimestamp.getTime() > o.getLeaveTime().getTime())
			{
				liste.add("ERROR:Occaional User Has Entered Invalid Leave Time");
				tempMsg.setStatusMsg("Leave Time Must Be After Current Time");
				return;
			}
			//TODO:CHECK if Lot is Full
			if (AdminOrders.insert(o)) {
				tempMsg.setStatus(true);
				liste.add("Occasional Client Has Added Order No."+o.getOid());
			} else {
				tempMsg.setStatus(false);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void AddTemporaryOrder(Object msg) {
		Message tempMsg = (Message) msg;
		try {

			if (AdminOrders.insert((Orders) tempMsg.getObj())) {
				tempMsg.setStatus(true);
				liste.add("Temorary Client Has Added Order No."+((Orders) tempMsg.getObj()).getOid());
			} else {
				tempMsg.setStatus(false);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	private void AddSubscriberOrder(Object msg) {
		Message tempMsg = (Message) msg;
		try {
			long time = System.currentTimeMillis();
			Timestamp currTimestamp = new Timestamp(time);
			Orders o = (Orders) tempMsg.getObj();
			o.setStartTime(currTimestamp);
			if (AdminOrders.insert((Orders) tempMsg.getObj())) {
				tempMsg.setStatus(true);
				liste.add(((Orders)tempMsg.getObj()).getType() + " Subscriber Client Has Added Order No." + ((Orders) tempMsg.getObj()).getOid());
			} else {
				tempMsg.setStatus(false);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	/*private void CancellOrder(Object msg) {
		Timestamp s1=new Timestamp();
		Message tempMsg = (Message) msg;
		int id= ((Orders) tempMsg.getObj()).getOid();
		Orders order=new Orders();
		try {			
			long time = System.currentTimeMillis();
			java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
			order= AdminOrders.getRow(id);		//get the order detail from data base
			if(order.getType().equals("Temporary")){			//cancel only temporary orders
				liste.add("Get order Temporary deatils od orderid: "+ id +"  "+ timestamp);				
			}
						
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}*/
	
	private void complaintHandle(Object msg) {
		//Timestamp s1=new Timestamp();
		Message tempMsg = (Message) msg;
		/* time
		long time = System.currentTimeMillis();
		Timestamp currTimestamp = new Timestamp(time);
	//	bean.setStartTime(currTimestamp.toString());*/
		
		
		int id= ((Orders) tempMsg.getObj()).getOid();
		Orders order=new Orders();
		try {			
			order= AdminOrders.getRow(id);		//get the order detail from data base
			if(order.getType().equals("Temporary")){			//cancel only temporary orders
	//			liste.add("Get order Temporary deatils od orderid: "+ id +"  "+ timestamp);				
			}
						
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	

	
}
